/*
* UserManager.java
* Created on  2013-10-21 上午7:44
* 版本       修改时间          作者      修改内容
* V1.0.1    2013-10-21       gaoxinyu    初始版本
*
*/
package com.genghis.ptas.security.service.impl;

import com.genghis.core.page.entity.Page;
import com.genghis.core.page.entity.PageParameter;
import com.genghis.ptas.classify.entity.TypeValues;
import com.genghis.ptas.constant.DictConstant;
import com.genghis.ptas.course.dao.CourseCollectDao;
import com.genghis.ptas.course.dao.CourseDao;
import com.genghis.ptas.course.service.CourseRegisterService;
import com.genghis.ptas.friend.dao.FriendDao;
import com.genghis.ptas.friend.entity.Friend;
import com.genghis.ptas.inbox.dao.InboxDao;
import com.genghis.ptas.inbox.entity.Inbox;
import com.genghis.ptas.note.entity.Note;
import com.genghis.ptas.note.service.NoteService;
import com.genghis.ptas.security.dao.RoleDao;
import com.genghis.ptas.security.dao.UserDao;
import com.genghis.ptas.security.dao.UserRoleDao;
import com.genghis.ptas.security.entity.Role;
import com.genghis.ptas.security.entity.User;
import com.genghis.ptas.security.entity.UserBaseInfo;
import com.genghis.ptas.security.entity.UserRole;
import com.genghis.ptas.security.service.UserService;
import com.genghis.ptas.system.service.DictService;
import com.genghis.ptas.util.DateUtil;
import com.genghis.ptas.util.FileUp;
import com.genghis.ptas.util.LoginUserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xml.sax.SAXException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author gaoxinyu
 * @version 1.0.1
 */
@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private DictService dictService;

    @Autowired
    private NoteService noteService;

    @Autowired
    private CourseRegisterService courseRegisterService;

    @Autowired
    private CourseCollectDao courseCollectDao;

    @Autowired
    private CourseDao courseDao;

    @Autowired
    private FriendDao friendDao;

    @Autowired
    private InboxDao inboxDao;

    private String Md5(String plainText) {
        StringBuilder buf = new StringBuilder("");
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();
            int i;
            for (byte aB : b) {
                i = aB;
                if (i < 0) i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return buf.toString().toUpperCase();
    }

    @Override
    public Page<User> findUserPageList(PageParameter pageParameter, User user) {
        return userDao.findUserPageList(pageParameter, user);
    }

    @Override
    public User findUserAllInfoById(int id) {
        try {
            UserBaseInfo userBaseInfo = userDao.findUserBaseInfoByUserId(id);
            User user = userDao.findUserAllInfoById(id);
            user.setUserBaseInfo(userBaseInfo);
            return user;
        } catch (Exception e) {
            System.out.print("用户已经不存在");
            return null;
        }


    }

    @Override
    public User findUserByLoginName(String loginName) {
        return userDao.findUserByLoginName(loginName);
    }

    @Override
    public Boolean checkRepeatLoginName(String loginName, String oldName) {
        Boolean hasLoginName = userDao.checkRepeatLoginName(loginName);
        return !(hasLoginName && !oldName.equals(loginName));
    }

    @Override
    public Boolean checkRepeatUserName(String userName, String oldName) {
        Boolean hasLoginName = userDao.checkRepeatUserName(userName);
        return !(hasLoginName && !oldName.equals(userName));
    }

    @Override
    public int addUser(User user) {
        user.setPassword(Md5(user.getPassword()));
        int id = userDao.addUser(user);
        user.setId(id);
        friendDao.addFriendInfo(new Friend(id));
        addUserRole(user, id);
        addUserBaseInfo(user, id);
        addFirstInbox(user);
        return id;
    }

    private void addFirstInbox(User user) {
        Inbox inbox = new Inbox();
        inbox.setContent("欢迎使用SCORM学习平台! " +
                "祝您太该平台上学习愉快，学有所成，找到自己的学习天地!");
        inbox.setSendDate(DateUtil.getSystemDate(DictConstant.DATE_FORMAT));
        inbox.setUserId(user.getId());
        inbox.setState(DictConstant.INBOX_STATE_0);
        inbox.setCategory(DictConstant.INBOX_CATEGORY_1);
        inbox.setAddresseeId(0);
        inboxDao.addInbox(inbox);
    }

    private void addUserBaseInfo(User user, int id) {
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        if (user.getUserBaseInfo() != null) {
            userBaseInfo = user.getUserBaseInfo();
        }
        userBaseInfo.setUserId(id);
        userBaseInfo.setExperience(DictConstant.VOID_VALUE);
        userBaseInfo.setSex(DictConstant.VOID_VALUE);
        userBaseInfo.setEducation(DictConstant.VOID_VALUE);
        userBaseInfo.setPhotoUrl(DictConstant.DEFAULT_USER_PHOTO_URL);
        userDao.addUserBaseInfo(userBaseInfo);
    }

    private void addUserRole(User user, int id) {
        UserRole userRole = new UserRole();
        userRole.setRoleId(user.getRoleId());
        userRole.setUserId(id);
        userRoleDao.addUserRole(userRole);
    }

    @Override
    public void editUser(User user) {
        UserRole userRole = new UserRole();
        if ("".equals(user.getShowRoleId()) || null == user.getShowRoleId()) {
            userRole.setRoleId(user.getRoleId());
        } else {
            userRole.setRoleId(roleDao.findRoleByRoleName(user.getShowRoleId()).getId());
        }
        userRole.setUserId(user.getId());
        userRoleDao.editRoleByUserId(userRole);
        userDao.editUser(user);
    }

    @Override
    public void editUserBaseInfo(UserBaseInfo userBaseInfo) {
        userBaseInfo.setEducation(dictService.changeDictValueToCode(userBaseInfo.getShowEducation(), DictConstant.EDUCATION_DICT));
        userDao.editUserBaseInfo(userBaseInfo);
    }

    @Override
    public void delUsers(String userIds[]) {
        for (String userId : userIds) {
            userDao.delUser(Integer.parseInt(userId));
            userRoleDao.deleteUserRoleByUserId(userId);
            friendDao.delFriendInfoByUserId(userId);
        }
    }

    @Override
    public UserBaseInfo findUserBaseInfoByUserId(int userId) {
        return userDao.findUserBaseInfoByUserId(userId);
    }

    @Override
    public User findFullUserByUserLoginName(String loginName) {
        User user = userDao.findUserByLoginName(loginName);
        user.setUserBaseInfo(userDao.findUserBaseInfoByUserId(user.getId()));
        return user;
    }

    @Override
    public void upPhoto(HttpServletRequest request, String upPhoto) throws ServletException, IOException, ParserConfigurationException, SAXException,
            XPathExpressionException {
        String loginName = LoginUserUtil.findLoginUserName();
        User user = userDao.findUserByLoginName(loginName);
        UserBaseInfo userBaseInfo = userDao.findUserBaseInfoByUserId(user.getId());
        FileUp fileUp = new FileUp();
        String photoUrl = fileUp.upPhoto(request, upPhoto);
        userBaseInfo.setPhotoUrl(photoUrl);
        userDao.editUserBaseInfo(userBaseInfo);
    }

    @Override
    public boolean checkUserPassword(String password) {
        String loginName = LoginUserUtil.findLoginUserName();
        return userDao.checkUserPassword(Md5(password), loginName);
    }

    @Override
    public void editUserPassWord(String password, String loginName) {
        User user = findUserByLoginName(loginName);
        user.setPassword(Md5(password));
        userDao.editUser(user);
    }

    @Override
    public String returnIndexPage(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String loginName = LoginUserUtil.findLoginUserName();
        if (null == loginName || "".equals(loginName)) {
            request.setAttribute("isLogin", false);
            request.setAttribute("notLogin", true);
            return "frontstage/public/index";
        }

        User user = findFullUserByUserLoginName(loginName);
        ServletContext application = session.getServletContext();
        List<String> onlineUserList = (List<String>) application.getAttribute("onlineUserList");
        if (null == onlineUserList)
            onlineUserList = new ArrayList<String>();
        if (!onlineUserList.contains(user.getLoginName())) {
            onlineUserList.add(user.getLoginName());
        }
        application.setAttribute("onlineUserList", onlineUserList);

        session.setAttribute("user", user);
        Role role = roleDao.findRoleByUserId(user.getId());
        request.setAttribute("countNote", countNote(user.getId()));
        request.setAttribute("countRegisterCourse", countRegisterCourse(user.getId()));
        request.setAttribute("countCollectCourse", countCollectCourse(user.getId()));
        request.setAttribute("countUploadCourse", countUploadCourse(user.getId()));
        request.setAttribute("isLogin", true);
        request.setAttribute("notLogin", false);
        request.setAttribute("user", user);
        if (!DictConstant.ROLE_USER.equals(role.getRoleName())) {
            request.setAttribute("isSystem", true);
            return "backstage/index";
        }
        request.setAttribute("isSystem", false);
        return "frontstage/public/index";
    }

    @Override
    public Boolean forgetPassword(String loginName, String question) {
        User user = findFullUserByUserLoginName(loginName);
        return question.equals(user.getUserBaseInfo().getQuestion());
    }

    @Override
    public void resetPassword(String loginName, String password) {
        userDao.resetPassword(loginName, Md5(password));
    }

    private int countUploadCourse(int userId) {
        return courseDao.findUploadCourseListByUserId(userId).size();
    }

    private int countCollectCourse(int userId) {
        return courseCollectDao.findCourseCollectByUserId(userId).size();
    }

    private int countRegisterCourse(int userId) {
        return courseRegisterService.findCourseRegisterByUserId(userId).size();
    }

    private int countNote(int userId) {
        List<TypeValues> notes = noteService.findAllNote(new Note("", "", 0, userId));
        int countNote = 0;
        for (TypeValues typeValues : notes) {
            countNote += typeValues.getNotes().size();
        }
        return countNote;
    }
}